package com.ruoyi.framework.security.filter;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.mapper.SysUserMapper;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

/**
 * 微信小程序认证过滤器 专门处理微信小程序的token验证
 */
@Order(80) // 使用@Order注解指定顺序，值越小越先执行
@Component
public class WxAuthFilter extends OncePerRequestFilter implements Ordered {

    @Override
    public int getOrder() {
        return 80;
    }

    // Redis中微信token的前缀，用于与系统其他token区分
    private static final String WX_TOKEN_PREFIX = "wx_token:";

    // 微信小程序接口的基础路径，用于过滤需要处理的请求
    private static final String WX_API_PREFIX = "/wx/";

    // Jackson的JSON处理工具（Spring默认已集成）
    // private static final ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    // @Autowired
    // private YjzUserMapper yjzUserMapper;
    @Autowired
    private SysUserMapper sysUserMapper;

    // 移除原writeErrorResponse方法，替换为抛出异常
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {
        if (request.getRequestURI().startsWith(WX_API_PREFIX)) {
            String wxToken = request.getHeader("Wx-Token");

            if (isPublicWxApi(request.getRequestURI())) {
                filterChain.doFilter(request, response);
                return;
            }

            // 验证token是否存在
            if (!StringUtils.hasText(wxToken)) {
                throw new WxAuthenticationException("微信登录凭证不存在，请重新登录");
            }

            // 从Redis获取用户ID
            String userIdStr = stringRedisTemplate.opsForValue().get(WX_TOKEN_PREFIX + wxToken);
            if (!StringUtils.hasText(userIdStr)) {
                throw new WxAuthenticationException("微信登录凭证已过期，请重新登录");
            }

            // 刷新token有效期
            stringRedisTemplate.expire(WX_TOKEN_PREFIX + wxToken, 7, TimeUnit.DAYS);

            // 查询用户信息
            Long userId;
            try {
                userId = Long.parseLong(userIdStr);
            } catch (NumberFormatException e) {
                throw new WxAuthenticationException("用户ID格式错误");
            }

            SysUser user = sysUserMapper.selectUserById(userId);
            // yjzUserMapper.selectById(userId);
            // if (user == null) {
            // throw new WxAuthenticationException("用户不存在");
            // }

            // 设置认证信息
            UsernamePasswordAuthenticationToken authentication =
                new UsernamePasswordAuthenticationToken(user, null, null);
            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }

        filterChain.doFilter(request, response);
    }

    /**
     * 判断是否为微信公开接口
     */
    private boolean isPublicWxApi(String requestUri) {
        return requestUri.startsWith("/wx/user/login") || requestUri.startsWith("/wx/user/register")
            || requestUri.startsWith("/wx/user/privacy");
    }

}